 ///
 /// @file    add.cc
 /// @author  lemon(haohb13@gmail.com)
 /// @date    2016-03-07 11:18:25
 ///
 
#include <string.h>
#include <iostream>

// 这样一个函数模板可以看成是一个代码生成器
template <typename T>
T add(const T & a, const T & b)
{
	return a + b;
}

// 模板特化
template <>
const char * add<const char *>(const char * const & a,
		const char * const & b)
{
	std::cout << "template <> add(char *, char *)" << std::endl;
	char * ptmp = new char [strlen(a) + strlen(b) + 1];
	strcpy(ptmp, a);
	strcat(ptmp, b);
	return ptmp;
}


#if 1
const char * add(const char * p1, const char * p2)
{
	std::cout << "add(const char *, const char *)" << std::endl;
	char * ptmp = new char[strlen(p1) + strlen(p2) + 1];
	strcpy(ptmp, p1);
	strcat(ptmp, p2);
	return ptmp;
}
#endif

#if 0
//这两个函数是由编译器根据参数通过函数模板推导出来的
// 模板函数
int add(const int & a, const int b)
{
	return a + b;
}

double add(const double & a, const double & b)
{
	return a + b;
}
#endif

//模板参数有两种形式：
//１.　类类型
//２.非类型参数，必须是int型
template <typename T, int NUM>
T fun(T a)
{
	return a * NUM;
}
#if 0
template <typename T, int NUM>
int fun(T a)
{
	return a * NUM;
}
int func(int a1, int a2);
double func(int a3, int a4);
#endif

int main(void)
{
	std::cout << add(10, 20) << std::endl;//隐式实例化
	std::cout << add(11.0, 22.22) << std::endl;
	const char * p1 = "hello";
	const char * p2 = "world";
	const char * p3 = add(p1, p2);
	std::cout << p3 << std::endl;

	std::cout << fun<int, 10>(10) << std::endl;//显式实例化
	return 0;
}

